<!DOCTYPE html>
<html>

<style>
    #root {
        display: flex;
    }

    #left {
        width: 70%;
        display: inline-block;
    }

    #right {
        display: flex;
        justify-content: flex-start;
        /* 水平左对齐 */
        align-items: flex-start;
        /* 垂直上对齐 */
        margin-left: 5%;
        width: 30%;
        display: inline-block;
    }

    #boxes {
        margin-top: 10px;
    }

    #count {
        width: 20px;
    }

    .row {
        display: block;
    }

    .white {
        background-color: azure;
    }

    .blue {
        background-color: aqua;
    }
</style>

<body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root">
        <div id="left">

            <div id="dplayer"></div>
        </div>
        <div id="right">
            <span class="row">
                <button id="refresh">refresh</button>
                <span id="count"></span>
                <button id="follow" class="white">follow(x)</button>
            </span>

            <span id="info" class="row"></span>
            <span id="info2" class="row"></span>
            <div id="boxes"></div>
        </div>

    </div>
    <!-- <script src="https://cdn.jsdelivr.net/npm/hls.js@1.1.5/dist/hls.min.js" async>
    </script>
    <script src="https://cdn.jsdelivr.net/npm/dplayer@1.26.0/dist/DPlayer.min.js" async>
    </script> -->
    <script src="flv.min.js"></script>
    <script src="hls.min.js"></script>
    <script src="DPlayer.min.js"></script>
    <script>
        let isString = (x) => {
            return typeof x === 'string';
        }

        let isList = (x) => {
            return Array.isArray(x);
        }

        let isObj = (x) => {
            return typeof x === 'object';
        }

        let updateObj = (dst, src) => {
            for (let key in src) {
                dst[key] = src[key]
            }
            return dst;
        }



        let refresh = document.getElementById('refresh');
        let count = document.getElementById('count');
        let follow = document.getElementById('follow');
        let div = document.getElementById('boxes');
        let info = document.getElementById('info');
        let info2 = document.getElementById('info2');

        let PLAYER = null;
        let url = "http://server.lan:19999/files/videos/group_11_tv_tv1/09_%E5%B0%84%E9%9B%95_%E7%A5%9E%E9%9B%95/%E5%B0%84%E9%9B%95%E8%8B%B1%E9%9B%84%E4%BC%A0%281983%29/%E5%B0%84%E9%9B%95%E8%8B%B1%E9%9B%84%E4%BC%A0%EF%BC%881983%EF%BC%89S01E02.1080P.mkv";

        const URL_proxy = "http://x.tv.server.lan:19999"
        let getVideoUrl = (u) => {
            let index = u.indexOf(URL_proxy+"/");
            if (index >= 0) {
                return u;
            }

            // 本地视频
            if (u.indexOf("server.lan:19999/") >= 0) {
                return u;
                // return "/" + u.substring(index + x.length);
            }
            // xiao ya
            if (u.indexOf(":5678/d/") >= 0) {
                return u;
                // return "/" + u.substring(index + x.length);
            }

            if (u.indexOf(":35455/")>0){
                return URL_proxy + "/api/proxy?url=" + encodeURIComponent(u) + "&stream=yes";
            }

            if (u.indexOf(".m3u8") > 0) {
                return u;
                // return URL_proxy + "/api/proxy?url=" + encodeURIComponent(u) + "&stream=yes";
            }

            return URL_proxy + "/api/proxy?url=" + encodeURIComponent(u) + "&stream=yes";

            // return location.origin + 
            // return u;
        }

        let getVideoType = (url) => {

            // u.endsWith; x.startsWith
            if (url.indexOf(":19999/api/live/douyu/") >= 0) {
                return "flv";
            }
            if (url.indexOf(":19999/api/live/bilibili/") >= 0) {
                return "flv";
            }
            if (url.indexOf(".m3u") >= 0) {
                return "hls";
            }
            // if (url.endswith(".mp4")||url.endswith(".mkv")) {
            //     return "auto";
            // }
            return "flv";
            // if (url.indexOf(".m3u") >= 0) {
            // }
            // return "auto";
            // // return "flv";
        }

        let tc = (func) => {
            // tc = try catch
            try {
                func();
            } catch (error) {

            }
        }
        let prePlayer = (dp) => {
            if (!dp) return;
            tc(() => {
                dp.destroy();
                console.log("dp.destroy");
            });
            PLAYER = null;
        }

        let preSwitch = (dp) => {
            if (!dp) return;
            tc(dp.pause);
            tc(() => {
                if (dp.hls) {
                    dp.hls.destroy();
                }
            });
            tc(() => {
                const mediaSource = PLAYER.mediaSource; // 获取 MediaSource 对象
                // 关闭并清除所有 SourceBuffer
                const sourceBuffers = mediaSource.sourceBuffers;
                while (sourceBuffers.length > 0) {
                    mediaSource.removeSourceBuffer(sourceBuffers[0]);
                }
            })
        }

        // let prePlayer = null;
        let play = (url, header) => {
            let url1 = getVideoUrl(url);
            let vtype;// = getVideoType(url);
            if (url1.indexOf("tv.server.lan:19999/api")<0) {
                vtype = "auto";
            } else {
                vtype = getVideoType(url);
            }
            console.log(`[play] type=${vtype}, url=${url}`);

            info.innerText = url;
            info2.innerText = url1;
            // if (prePlayer) {
            //     try {
            //         // 销毁, 不然会一直在load data.
            //         prePlayer.destroy();
            //     } catch (e) {

            //     }
            // }

            let video = {
                url: url1,
                type: vtype,
            };

            prePlayer(PLAYER);
            if (!PLAYER) {
                let dp = new DPlayer({
                    container: document.getElementById('dplayer'),
                    video: video,
                    autoplay: true,
                    crossOrigin: 'anonymous',
                });

                // prePlayer = dp;

                // dp.on('canplay', function () {
                //     console.log('player canplay');
                //     dp.play();
                // });

                PLAYER = dp
            } else {
                preSwitch(PLAYER);
                PLAYER.switchVideo(video);
            }

            PLAYER.notice(url, 2000);
            // dp.on('error', function () {
            //     console.log('player error');
            //     try {
            //         dp.destroy();
            //     } catch (e) {

            //     }

            //     // dp.play();
            // });
            // setTimeout(()=>{

            // },1000);
        }


        let playObj = (obj) => {
            let url0 = obj.playUrl;
            let u = obj.url;
            let url = url0 ? url0 : "";
            try {
                if (isString(u)) {
                    url += u;
                    console.log("string:", url);
                } else if (isObj(u)) {
                    let values = u.values;
                    console.log("obj:", u);

                    if (isList(values)) {
                        console.log("list:values:", values);
                        url += values[0].v
                    } else {
                        url += values.v
                    }
                }
            } catch (e) {
                console.log("[E] playObj err");
                return
            }

            let header = obj.header;
            play(url, header);
        }


        let y;

        const OBJ = {};// map[string]json_string
        let api = "/api/playing"
        let playingKey = null;
        let playingObj = null;
        let is_follow = false;//自动跟随 json,播放最新的视频

        let play_by_key = (key) => {
            let obj = OBJ[key];
            if (obj) {
                playingKey = key;
                playingObj = obj;
                playObj(JSON.parse(obj));
                y = obj;
            }
        }

        let is_sameVideo = (key) => {
            if (playingKey && key == playingKey) {
                let obj = OBJ[playingKey];
                let tag = "same:";
                if (obj == playingObj) {
                    return true;
                }
            }
            return false;
        }

        let countX = 0;
        let updateTime = (n) => {
            if (n % 3 == 0) {
                const d = new Date();
                const hour = d.getHours();
                const min = d.getMinutes();
                count.innerText = `${hour}:${min}`;
            }
        }

        let upatePlayingState = () => {
            if (playingKey) {
                let obj = OBJ[playingKey];
                let tag = "same:";
                if (obj == playingObj) {
                } else {
                    if (is_follow) {
                        tag = "not same:"
                        play_by_key(playingKey);
                        console.log(tag, playingKey, obj);
                    }
                }
                countX++;
                updateTime(countX);
            }
        }

        let btns = {};
        btns.clearChild = () => {
            while (div.firstChild) {
                div.removeChild(div.firstChild);
            }
        }

        btns.appendChild = (key) => {
            let obj = OBJ[key];
            let jo = JSON.parse(obj);
            let el = document.createElement("button")
            el.className = "row";
            el.innerText = key + " : " + jo.name;

            div.appendChild(el);
            el.addEventListener("click", (ev) => {
                if (is_sameVideo(key)) {
                    return;
                }
                console.log(jo.name);
                play_by_key(key);
            })
        }

        let act = (playNew) => {
            fetch(api).then(
                res => res.json()
            ).then(jo => {
                // console.log(jo);
                updateObj(OBJ, jo)
                jo = OBJ;
                let length = Object.keys(jo).length;
                if (length < 1) return;

                btns.clearChild();

                for (let key in jo) {
                    let obj = jo[key];
                    console.log(key);
                    if (playNew) {
                        playNew = false;
                        play_by_key(key);
                    }

                    btns.appendChild(key);
                }

                if (!playNew) {
                    upatePlayingState();
                }
                // if (length == 1) {
                //     playObj(JSON.parse(obj0))
                // }
            }).catch(err => {
                console.log("[e] fetch error:", err);
            });
        }
        act(true);

        refresh.addEventListener("click", () => {
            act(false);
        });

        follow.addEventListener("click", () => {
            is_follow = !is_follow;
            if (is_follow) {
                follow.innerText = "follow(√)";
                follow.className = "blue";
            } else {
                follow.innerText = "follow(×)";
                follow.className = "white";
            }
        });

        setInterval(() => {
            act(false);
        }, 5000);

    </script>
</body>

</html>


